package com.winchain.chainbill.chain.service.impl;

import com.shell.bee.acct.account.po.AcctBas;
import com.shell.bee.acct.transaction.po.AcctTxRec;
import com.shell.bee.base.utils.Encryptor;
import com.shell.bee.base.utils.SystemUtil;
import com.shell.stellar.StellarTransaction;
import com.shell.stellar.StellarTransaction.Destination;
import com.shell.stellar.service.StellarTxService;
import com.winchain.chainbill.ChainBillUtil;
import com.winchain.chainbill.chain.ChainTxService;
import com.winchain.chainbill.trade.service.BillAcctService;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.stellar.sdk.Memo;
import org.stellar.sdk.xdr.TransactionResultCode;

@Service("chainTxService")
public class ChainTxServiceImpl implements ChainTxService {
	@Autowired
	private BillAcctService billAcctService;
	@Autowired
	private StellarTxService stellarTxService;

	public Map<String, String> fire(AcctTxRec tx) throws IOException {
		Map<String, String> result = null;
		if (!ChainBillUtil.onChain()) {
			result = new HashMap();
			result.put("ret_code", "S");
			result.put("tx_sn", SystemUtil.getUUID());
		} else {
			AcctBas sourceAcct = this.billAcctService.getAcctBas(tx.getTxAcctNo());
			String txAcctPassword = Encryptor.decrypt(sourceAcct.getAcctKey());

			List<StellarTransaction.Destination> destinations = new ArrayList();
			destinations.add(buildDestination(tx));

			StellarTransaction stellarTransaction = new StellarTransaction();
			stellarTransaction.setSource(txAcctPassword);
			stellarTransaction.setMemo(Memo.text(tx.getTxAbs()));
			stellarTransaction.setDestinatins(destinations);

			result = this.stellarTxService.trans(stellarTransaction);
			result = convertResult(result);
		}
		return result;
	}

	public Map<String, String> fire(String source, List<AcctTxRec> txs) throws IOException {
		Map<String, String> result = null;
		if (!ChainBillUtil.onChain()) {
			result = new HashMap();
			result.put("ret_code", "S");
			result.put("tx_sn", SystemUtil.getUUID());
		} else {
			StellarTransaction stellarTransaction = new StellarTransaction();
			List<StellarTransaction.Destination> destinations = new ArrayList();
			for (AcctTxRec AcctTxRec : txs) {
				if (source == null) {
					AcctBas sourceAcct = this.billAcctService.getAcctBas(AcctTxRec.getTxAcctNo());
					source = sourceAcct.getAcctKey();
				}
				destinations.add(buildDestination(AcctTxRec));
			}
			source = Encryptor.decrypt(source);
			stellarTransaction.setSource(source);
			stellarTransaction.setMemo(Memo.text(((AcctTxRec) txs.get(0)).getTxAbs()));
			stellarTransaction.setDestinatins(destinations);
			result = this.stellarTxService.trans(stellarTransaction);
			result = convertResult(result);
		}
		return result;
	}

	private StellarTransaction.Destination buildDestination(AcctTxRec tx) {
		return StellarTransaction.Destination.build(tx.getCpAcctNo(), tx.getCurrCode(), tx.getTxAmt().toString());
	}

	private Map<String, String> convertResult(Map<String, String> result) {
		Map<String, String> ret = new HashMap();
		String retCode = "S";
		if (!TransactionResultCode.txSUCCESS.toString().equals(result.get("RESULT_CODE"))) {
			retCode = "F";
		}
		ret.put("ret_code", retCode);
		ret.put("tx_sn", result.get("RESULT_HASH"));
		return ret;
	}
}
